using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows;
using Microsoft.Practices.CompositeUI;
using Microsoft.Practices.CompositeUI.Utility;
using Microsoft.Practices.ObjectBuilder;

namespace SCSFContrib.CompositeUI.WPF.Activation
{
	/// <summary>
	/// Implements a <see cref="BuilderStrategy"/> that ensures any <see cref="FrameworkContentElement"/>s are added or removed from
	/// the resident <see cref="IFrameworkContentElementActivationService"/> implementation.
	/// </summary>
	public sealed class FrameworkContentElementActivationStrategy : BuilderStrategy
	{
		private static readonly DependencyResolutionLocatorKey _workItemLocatorKey = new DependencyResolutionLocatorKey(typeof(WorkItem), null);

		/// <summary>
		/// Builds up this activation strategy.
		/// </summary>
		/// <param name="context">
		/// The context for the operation.
		/// </param>
		/// <param name="typeToBuild">
		/// The type of object that is being requested.
		/// </param>
		/// <param name="existing">
		/// The existing instance, if one was passed in, or if a previous strategy has already created the object.
		/// </param>
		/// <param name="idToBuild">
		/// The ID of the object that is being requested. May be <see langword="null"/> if the user requested an unnamed instance.
		/// </param>
		/// <returns>
		/// The built object.
		/// </returns>
		public override object BuildUp(IBuilderContext context, Type typeToBuild, object existing, string idToBuild)
		{
			Guard.ArgumentNotNull(context, "context");
			FrameworkContentElement frameworkContentElement = existing as FrameworkContentElement;

			if (frameworkContentElement != null)
			{
				WorkItem workItem = context.Locator.Get<WorkItem>(_workItemLocatorKey);
				Debug.Assert(workItem != null);
				workItem.Services.Get<IFrameworkContentElementActivationService>(true).FrameworkContentElementAdded(frameworkContentElement);
			}

			return base.BuildUp(context, typeToBuild, existing, idToBuild);
		}

		/// <summary>
		/// Tears down this activation strategy.
		/// </summary>
		/// <param name="context">
		/// The context for the operation.
		/// </param>
		/// <param name="item">
		/// The item that is being unbuilt.
		/// </param>
		/// <returns>
		/// The unbuilt item.
		/// </returns>
		public override object TearDown(IBuilderContext context, object item)
		{
			Guard.ArgumentNotNull(context, "context");
			FrameworkContentElement frameworkContentElement = item as FrameworkContentElement;

			if (frameworkContentElement != null)
			{
				WorkItem workItem = context.Locator.Get<WorkItem>(_workItemLocatorKey);
				Debug.Assert(workItem != null);
				workItem.Services.Get<IFrameworkContentElementActivationService>(true).FrameworkContentElementRemoved(frameworkContentElement);
			}

			return base.TearDown(context, item);
		}
	}
}